package dm.ast;

import test.envset.GlobalState;

import java.util.ArrayList;

/**
 * 布尔表达式
 */
public class DmBoolExpression extends DmExpression {
    public final static DmDataType reType = DmDataType.BOOLEAN;  //表达式的返回类型

    DmOperator op = null;  //运算符

    boolean notFlag = false;  //not 运算符标志

    int AllOrSomeOrAny = 0;


    public void setAllOrSomeOrAny(int allOrSomeOrAny) {
        AllOrSomeOrAny = allOrSomeOrAny;
    }

    @Override
    public DmDataType getExpressionType() {
        return reType;
    }

    public void setLeftExp(DmExpression leftExp) {
        this.expLeft = leftExp;
    }

    public DmExpression getLeftExp() {
        return (DmExpression) this.expLeft;
    }

    public void setRightExp(DmExpression rightExp) {
        this.expRight = rightExp;
    }

    public DmExpression getRightExp() {
        return (DmExpression) this.expRight;
    }

    public void setOperator(DmOperator op) {
        this.op = op;
    }

    public void setNotFlag(boolean notflag) {
        this.notFlag = notflag;
    }

    public DmOperator getOperator() {
        return this.op;
    }

    @Override
    public void setWidt() {
        if (expLeft == null) {
            wid_t = 3;
        } else {
            expLeft.setWidt();
            wid_t = expLeft.getWidt();
            if (op != null) {
                wid_t += op.getWidt();
            }
            if (expRight != null) {
                expRight.setWidt();
                wid_t += expRight.getWidt();
            }
        }
    }

    @Override
    public void setDept() {
        if (expLeft == null) {
            dep_t = 1;
        } else {
            expLeft.setDept();
            dep_t = expLeft.getDept();
            if (expRight != null) {
                expRight.setDept();
                if (expRight.getDept() > dep_t) {
                    dep_t = expRight.getDept();
                }
            }
        }
    }

    //通过1个表达式和一元操作符构造bool表达式
    //可构造复合bool表达式
    public static DmBoolExpression buildBoolExp(DmExpression exp, DmBoolOperator op) {
        DmBoolExpression boolExp = new DmBoolExpression();
        boolExp.setTargetDept(exp.target_dep);
        boolExp.setTargetWidt(exp.target_wid + 1);
        boolExp.setLeftExp(exp);
        boolExp.setOperator(op);
        return boolExp;
    }

    //通过2个表达式和二元操作符构造bool表达式
    //可构造复合bool表达式
    public static DmBoolExpression buildBoolExp(DmExpression lexp, DmExpression rexp, DmBoolOperator op) {
        DmBoolExpression boolExp = new DmBoolExpression();
        boolExp.setTargetDept(lexp.target_dep > rexp.target_dep ? lexp.target_dep : rexp.target_dep);
        boolExp.setTargetWidt(lexp.target_wid + 1 + rexp.target_wid);
        boolExp.setLeftExp(lexp);
        boolExp.setOperator(op);
        boolExp.setRightExp(rexp);
        return boolExp;
    }

    @Override
    public String toSql() {
        if (expLeft == null) {
            return " " + this.getClass().getSimpleName() + getSqlTarget();
        } else {
            if (op == null) {
                return expLeft.toSqlClose();
            } else {
                StringBuilder sql = new StringBuilder();
                sql.append(" ");
                if (op.getExpNum() == 2) { //二元操作符
                    sql.append(expLeft.toSqlClose());
                    sql.append(op.toSql());
                    if (AllOrSomeOrAny == 1) {
                        sql.append(" ALL " + expRight.toSqlClose());
                    } else if (AllOrSomeOrAny == 2) {
                        sql.append(" SOME " + expRight.toSqlClose());
                    } else if (AllOrSomeOrAny == 3) {
                        sql.append(" ANY " + expRight.toSqlClose());
                    } else {
                        sql.append(expRight.toSqlClose());
                    }
                } else { //一元操作符
                    if (op.getIsPre()) {
                        sql.append(op.toSql());
                        sql.append(expLeft.toSqlClose());
                    } else {
                        sql.append(expLeft.toSqlClose());
                        sql.append(op.toSql());
                    }
                }
                return sql.toString();
            }
        }
    }

    @Override
    public void fill(GlobalState globalState) {
        if (!isCompleted) {
            expLeft.fill(globalState);
            if (expRight != null) {
                expRight.fill(globalState);
            }
            isCompleted = true;
        }
    }
}
